namespace mathD
{
    export class Matrix3x2
    {
        public rawData: Float32Array;
        constructor(datas: Float32Array = null)
        {
            if (datas)
            {
                this.rawData = datas;
            }
            else
                this.rawData = new Float32Array([1, 0, 0, 0, 1, 0]);
        }
        toString(): string
        {
            return "[" + this.rawData[0] + "," + this.rawData[1] + "," + this.rawData[2] + "],"
                + "[" + this.rawData[3] + "," + this.rawData[4] + "," + this.rawData[5] + "]";
        }
        static Clone(src: Matrix3x2, out: Matrix3x2)
        {
            for (var i = 0; i < 16; i++)
            {
                out.rawData[i] = src.rawData[i];
            }
        }
        

        static MakeIdentity(out: Matrix3x2)
        {
            out.rawData[0] = 1;
            out.rawData[1] = 0;

            out.rawData[2] = 0;
            out.rawData[3] = 1;

            out.rawData[4] = 0;
            out.rawData[5] = 0;
        }
        static Decompose(src: Matrix3x2, scale: Vector2, rotation: angelref, translation: Vector2): boolean
        {
            //trans
            translation.x = src.rawData[4];
            translation.y = src.rawData[5];

            var xs = sign(src.rawData[0] * src.rawData[1]) < 0 ? -1 : 1;
            var ys = sign(src.rawData[2] * src.rawData[3]) < 0 ? -1 : 1;

            scale.x = xs * Math.sqrt(src.rawData[0] * src.rawData[0] + src.rawData[1] * src.rawData[1]);
            scale.y = ys * Math.sqrt(src.rawData[2] * src.rawData[2] + src.rawData[3] * src.rawData[3]);

            if (scale.x === 0 || scale.y === 0)
            {
                rotation.v = 0;
                return false;
            }

            var sx = src.rawData[0] / scale.x;
            var csx = src.rawData[1] / scale.x;
            var r1 = Math.asin(sx);
            var r2 = Math.acos(csx);
            rotation.v = r1;
            return true;
        }
        static Quaternion(matrix: Matrix, result: Quaternion): void 
        {
            var data = matrix.rawData;
            var m11 = data[0], m12 = data[4], m13 = data[8];
            var m21 = data[1], m22 = data[5], m23 = data[9];
            var m31 = data[2], m32 = data[6], m33 = data[10];
            var trace = m11 + m22 + m33;
            var s;

            if (trace > 0)
            {

                s = 0.5 / Math.sqrt(trace + 1.0);

                result.w = 0.25 / s;
                result.x = (m32 - m23) * s;
                result.y = (m13 - m31) * s;
                result.z = (m21 - m12) * s;
            } else if (m11 > m22 && m11 > m33)
            {

                s = 2.0 * Math.sqrt(1.0 + m11 - m22 - m33);

                result.w = (m32 - m23) / s;
                result.x = 0.25 * s;
                result.y = (m12 + m21) / s;
                result.z = (m13 + m31) / s;
            } else if (m22 > m33)
            {

                s = 2.0 * Math.sqrt(1.0 + m22 - m11 - m33);

                result.w = (m13 - m31) / s;
                result.x = (m12 + m21) / s;
                result.y = 0.25 * s;
                result.z = (m23 + m32) / s;
            } else
            {

                s = 2.0 * Math.sqrt(1.0 + m33 - m11 - m22);

                result.w = (m21 - m12) / s;
                result.x = (m13 + m31) / s;
                result.y = (m23 + m32) / s;
                result.z = 0.25 * s;
            }
        }
    }
    export class angelref
    {
        v: number;
    }
}